<template>
	<view class="chatInterface">
		<view class="scroll-view">
			<view class="all-history-loaded">
				{{allHistoryLoaded ? '已经没有更多的历史消息' : '下拉获取历史消息'}}
			</view>
			<!--已经收到的消息-->
			<view v-for="(message,index) in chatHistoryList" :key="message.sentTime">
				<!--时间显示，类似于微信，隔5分钟不发言，才显示时间-->
				<view class="time-lag">
					{{renderMessageDate(message, index)}}
				</view>
				<view class="message-item" :class="{'self' : message.senderUserId == currentUser}">
					<view class="avatar"
						  v-if="message.senderUserId != currentUser">
						  <!-- 获取聊天对象头像 -->
						<image :src="targetUrl"></image>
					</view>
					<view class="avatar" v-else>
						<!-- 获取自己头像 -->
						<image :src="selfHeadThumb"></image>
					</view>
					<view class="content">
<!-- 						<b class="pending" v-if="message.status == 'sending'"></b>
						<b class="send-fail" v-if="message.status == 'fail'"></b> -->
						<view v-if="message.messageType == 'RC:TxtMsg'" v-html="renderTextMessage(message)"></view>
						<image class="image-content" v-if="message.messageType == 'RC:ImgMsg'" :src="message.content.imageUri" :data-url="message.content.imageUri" @click="showImageFullScreen" mode="widthFix"></image>
						<view v-if="message.messageType == 'RC:HQVCMsg'" :class="playMsgid === message.messageUId ? 'text-content' : ''" :style="playMsgid === message.messageUId ? playVoiceStyle:''" @tap="playVoice(message)" v-html="renderVoiceMessage(message)"></view>
<!-- 						<view class="chatting-main" ref="list" id="list">
							<view class="time-message-block">
								<view class="opposite" :class="(message.senderUserId == currentUser) ? '' : 'mine'">
									<view v-if="message.messageType === 'RC:HQVCMsg' && message.content.duration >= 1" @tap="playVoice(message)" class="message-block"
										:class="playMsgid === message.messageUId ? 'play' : ''"
										:style="playMsgid === message.messageUId ? playVoiceStyle:''"
										style="width: 50vw; transition: all 0.1s linear">
										<view class="bubble voice" style="display: flex; justify-content: space-between"
											:class="playMsgid === message.messageUId ? 'play' : ''">
											<view class="length">{{
							  (message.content.duration < 1
								? message.content.duration + 1
								: message.content.duration) + 's'
							}}
											</view>
											<view class="icon my-voice"></view>
										</view>
									</view>
								</view>
							</view>
						</view> -->
					</view>
				</view>
			</view>
		</view>
		<view class="action-box" v-if="!video.visible">
			<view class="action-top">
				<view :class="[audio.visible ? 'record-icon record-open':'record-icon']" @click="switchAudioKeyboard"></view>
				<view class="record-input" @touchstart="onRecordStart" @touchend="onRecordEnd" v-if="audio.visible" @touchmove.stop.prevent="voiceIng" @touchcancel="voiceCancel">{{audio.recording ? '松开发送' : '按住录音'}}</view>
				<view v-if="!audio.visible" class="message-input">
					<!-- GoEasyIM最大支持3k的文本消息，如需发送长文本，需调整输入框maxlength值 -->
					<input type="text" maxlength="700" placeholder="发送消息" v-model="content" @focus="messageInputFocusin">
				</view>
				<view class="file-icon emoji-icon" @click="showEmoji"></view>
				<view class="file-icon more-icon" @click="showMore"></view>
				<span class="send-message-btn" @click="sendTextMessage">发送</span>
			</view>
			<!--展示表情列表-->
			<view class="action-bottom" v-if="emoji.show" style="justify-content: space-around">
				<image class="emoji-item" v-for="(emojiItem, emojiKey, index) in emoji.map" :key="index" :src="emoji.url + emojiItem" @click="selectEmoji(emojiKey)"></image>
			</view>
			<!--更多-->
			<view class="action-bottom" v-if="more.show">
				<view class="more-item" @click="toSendImage">
					<image src="../../../static/images/tupian.png"></image>
					<text>图片</text>
				</view>
<!-- 				<view class="more-item" @click="sendVideo">
					<image src="../../../static/images/shipin.png"></image>
					<text>视频</text>
				</view>
				<view class="more-item" @click="showCustomMessageForm">
					<image src="../../../static/images/zidingyi.png"></image>
					<text>自定义消息</text>
				</view> -->
			</view>
		</view>
		<!-- <view class="record-loading" v-if="audio.recording"></view> -->
		<view v-if="audio.recording" class="chatting-main">
			<view class="record" :class="audio.recording ? '' : 'hidden'">
				<view class="ing" :class="willStop ? 'hidden' : ''">
					<view class="icon luyin2"></view>
				</view>
				<view class="cancel" :class="willStop ? '' : 'hidden'">
					<view class="icon chehui"></view>
				</view>
				<view class="tis" :class="willStop ? 'change' : ''">{{ recordTis }}</view>
			</view>
		</view>
		<video v-if="video.visible" :src="video.url" id="videoPlayer" @fullscreenchange="onVideoFullScreenChange"></video>
	</view>
</template>

<script>
	import {
		ONLINE_SERVER_ADDRESS_BASE,
	} from "../../../util/network.js"
	import EmojiDecoder from "../../../lib/EmojiDecoder";
	import {
		CHATTER_TO,
		getTime,
		MSG_TYPE,
		rongEvent,
	} from '../../../util/rongCloud/messaging';
	import {
		beforeForSendFile,
		cloudSendMessage,
		getHistoryMsg,
		getMoreHistory,
		getOppoIdFrom,
		imService,
		RongIMLib,
	} from '../../../util/rongCloud/cloudUtil';
	import {
		isBlank,
		uniShowToast,
	} from '../../../util/misc.js'
	import {
		uniChooseImage,
	} from '../../../util/funcs.js'
	import {
		uploadQiNiu
	} from '../../../util/rongCloud/fileUtil'
	const recorderManager = uni.getRecorderManager();

	export default {
		name: "privateChat",
		// components : {
		// 	GoEasyAudioPlayer,
		// },
		watch: {
			chatHistoryList() {
				console.log('chatHistoryList', this.chatHistoryList);
			},
		},
		onNavigationBarButtonTap(){
			console.log("[info]","导航栏按钮触发监听")
			// this.$refs.popup.open('center')
			let url = '../conferenceRoom/list/list'
			
			uni.navigateTo({
				url:'../../report/report?id=' + this.id + '&name=' + this.name
			})
			// uni.navigateTo({
			// 	url:'@/pages/accessCardApplication/details/details?id=待分配' + '&state=' + '待申请'
			// })
		},
		data() {
			let emojiUrl = 'https://imgcache.qq.com/open/qcloud/tim/assets/emoji/';
			let emojiMap = {
				'[么么哒]': 'emoji_3@2x.png',
				'[乒乓]': 'emoji_4@2x.png',
				'[便便]': 'emoji_5@2x.png',
				'[信封]': 'emoji_6@2x.png',
				'[偷笑]': 'emoji_7@2x.png',
				'[傲慢]': 'emoji_8@2x.png'
			};
			return {
				id:-1,
				name:'',
				initFlag:false,
				//聊天文本框
				content: '',
				friend: null,
				currentUser: uni.getStorageSync('userinfo').rongCloud_id,
				//已经接收到的消息
				messages: [],
				chatHistoryList: [],
				//已经加载完所有历史消息
				allHistoryLoaded: false,

				//定义表情列表
				emoji : {
					url : emojiUrl,
					map : emojiMap,
                    show: false,
                    decoder:  new EmojiDecoder(emojiUrl, emojiMap),
				},
				more : {//更多按钮
					show : false
				},
				audio : {
					//语音录音中
					recording : false,
					//录音按钮展示
					visible : false
				},
				video : {
					visible : false,
					url : '',
					context : null
				},
				AUDIO: uni.createInnerAudioContext(),
				playMsgid: null,
				initPoint: {
					identifier: 0,
					Y: 0
				}, // 记录移动位置
				recordLength: 0,
				recordTimer: null,
				playVoiceStyle: '', //播放语音样式
				recordTis: '语音输入中', // 录音提示
				willStop: false, // 是否停止录音
				targetUrl:"",
				preView:`${ONLINE_SERVER_ADDRESS_BASE}/file/thumbnail-preview/`,
				selfHeadThumb:'',
			}
		},
		onReady () {
			this.video.context = uni.createVideoContext('videoPlayer',this);
			// https://uniapp.dcloud.io/api/ui/navigationbar?id=setnavigationbartitle
			// uni.setNavigationBarTitle({
			// 	title : this.friend.name
			// });
		},
		onLoad(option) {
			uni.removeTabBarBadge({
				index: 1,
			});
			this.targetUrl = option.targetUrl
			this.name = option.name
			this.managerId = option.id
		},
		onShow: async function() {
			this.more.show = false;
			this.emoji.show = false;
			let userInfo = uni.getStorageSync('userinfo')
			this.selfHeadThumb = this.preView + userInfo.headThumb
			if(!this.initFlag){
				this.add_listenToNewMessage();
				await this.initChatList();
				this.initFlag = true;
			}
		    // 录音监听器
		    this.initRecorderListeners();
		},
		onPullDownRefresh() {
			console.log('refresh');
			this.getMoreMsg()
			setTimeout(function () {
				uni.stopPullDownRefresh();
			}, 1000);
		},
		onUnload() {
			//退出聊天页面之前，清空页面传入的监听器
			uni.removeTabBarBadge({
				index: 1,
			});
			this.removeEventListen();
		},
		methods: {
			updateChatList(latestMessage) {
				if (!latestMessage || latestMessage.messageType == "RC:SRSMsg") return;
			
				// this.removeEventListen() // 融云的实现机制会导致触发多次
				let currentLast = this.chatHistoryList[
					this.chatHistoryList.length - 1
				] || {
					messageUId: ''
				};
				if (
					latestMessage &&
					latestMessage.messageUId != currentLast.messageUId // 只有在uid是不一样的时候才更新列表
				) {
					let tem = [].concat(this.chatHistoryList);
					// tem.push(latestMessage)
					this.chatHistoryList.push(latestMessage);
					this.scrollToBottom();
					// this.addEventListen()
				}
			},
			/**
			 * 注册监听聊天消息事件, 用于更新聊天列表
			 */
			add_listenToNewMessage() {
				uni.$on(rongEvent.chattingMessageSuccess, this.updateChatList);
			},
			removeEventListen() {
				uni.$off(rongEvent.chattingMessageSuccess, this.updateChatList);
			},
			clearInputMessage() {
				if (TESTING) {
					// this.inputMessage = 'test ' + getTime()
					this.content = 'test ' + getTime();
				} else {
					this.content = '';
				}
			},
			async sendMessageRong(msgObj, msgType) {
				// if (this.chattingHouseItem.id) this.chattingHouseItem = {};
			
				if (!msgObj) {
					if (isBlank(this.content)) {
						// 非空校验
						return;
					}
					msgObj = {
						content: this.content,
					};
				}
				let res = await cloudSendMessage(msgObj, msgType);
				// this.clearInputMessage();
			},
			async sendVoiceMessageRong(msgObj, msgType) {
				// if (this.chattingHouseItem.id) this.chattingHouseItem = {};
			
				if (!msgObj) {
					if (isBlank(this.content)) {
						// 非空校验
						return;
					}
					msgObj = {
						content: this.content,
					};
				}
				let res = await cloudSendMessage(msgObj, msgType);
				// this.clearInputMessage();
			},
			async initChatList() {
				let _this = this;
				if (this.previewingImage) return;
				getHistoryMsg()
					.then((res) => {
						_this.chatHistoryList = res.list;
					})
					.catch((error) => {
						console.log(error);
						uni.$once(rongEvent.connectSuccess, async () => {
							let result = await getHistoryMsg();
							// 只有链接成功了才能获取消息信息
							this.chatHistoryList = result.list;
							this.allHistoryLoaded = !result.hasMore;
							// this.afterChatListUpdate();
						});
					})
					// .finally(() => {
					// 	_this.afterChatListUpdate();
					// });
			},
			playAudioEffect(msgItem) {
				if (msgItem.messageUId !== this.playMsgid) return '';
				setTimeout(() => {
					return '';
				}, msgItem.content.duration * 1000);
				if (msgItem.senderUserId === this.currentUser.toString()) {
					return 'background: #0951b6';
				} else {
					return 'background: #c6ceda';
				}
			},
			// 播放语音
			playVoice(msg) {
				// console.log(msg)
				try {
					if (!msg) return;
					this.playMsgid = msg.messageUId;
					this.playVoiceStyle = this.playAudioEffect(msg)
					this.AUDIO.src = msg.content.remoteUrl;
					this.$nextTick(this.AUDIO.play());
				} catch (e) {
					console.log('播放错误:', e, msg);
				}
			},
            //渲染文本消息，如果包含表情，替换为图片
		    //todo:本不需要该方法，可以在标签里完成，但小程序有兼容性问题，被迫这样实现
            renderTextMessage(message) {
				return '<span class="text-content">' + this.emoji.decoder.decode(message.content.content) + '</span>'
            },
			renderVoiceMessage(message) {
				let spaceTemp = ''
				if(message.content.duration >= 10){
					spaceTemp = '&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp'
				}else{
					for (var i = 0; i < message.content.duration; i++) {
						spaceTemp += '&nbsp&nbsp&nbsp'
					}
				}
				let output = ''
				if(message.senderUserId == this.currentUser){
					output = '<span class="text-content">' + spaceTemp + (message.content.duration < 1 ? message.content.duration + 1 : message.content.duration) + 's' + '</span>'
				}else{
					output = '<span class="text-content">' + (message.content.duration < 1 ? message.content.duration + 1 : message.content.duration) + 's' + spaceTemp + '</span>'
				}
				return output
			},
            //像微信那样显示时间，如果有几分钟没发消息了，才显示时间
            //todo:本不需要该方法，可以在标签里完成，但小程序有兼容性问题，被迫这样实现
            renderMessageDate(message, index) {
                if (index === 0) {
                    return this.formatDate(message.sentTime)
                } else {
                    if (message.sentTime - this.chatHistoryList[index - 1].sentTime > 5 * 60 * 1000) {
                        return this.formatDate(message.sentTime)
                    }
                }
                return '';
            },
			initRecorderListeners(){
				// 监听录音开始
				this.AUDIO.onEnded((res) => {
					this.playMsgid = '';
					console.log('播放结束');
				});
				recorderManager.onStart(() => {
					this.audio.recording = true;
				});
				//录音结束后，发送
				recorderManager.onStop((res) => {
					this.audio.recording = false;
					this.recordEnd(res);
					console.log("录音结果",res)
				});
				// 监听录音报错
				recorderManager.onError(function(res){
					console.log("录音报错：",res);
				})
			},
			sendTextMessage() {//发送消息
				if (this.content.trim() !== '') {
					let body = this.content;
					if(this.content.length >= 50){
						body = this.content.substring(0,30)+"...";
					}
					this.sendMessageRong();
				}
				this.scrollToBottom();
				this.content = "";
			},
			async getMoreMsg() {
				console.log(this.chatHistoryList[0])
				let timeStamp = this.chatHistoryList[0].sentTime;
				let result = await getMoreHistory(timeStamp);
				console.log("下拉加载更多测试",result)
				this.allHistoryLoaded = !result.hasMore;
				for (let len = result.list.length, index = len - 1; index >= 0; index--) {
					let newMsg = result.list[index];
					this.chatHistoryList.unshift(newMsg);
				}
			},
			//语音录制按钮和键盘输入的切换
			switchAudioKeyboard() {
				this.audio.visible = !this.audio.visible;
				if(uni.authorize){
					uni.authorize({
						scope : 'scope.record'
					})
				}
			},
			voiceIng(e) {
				if (!this.audio.recording) {
					return;
				}
				let touche = e.touches[0];
				//上滑一个导航栏的高度触发上滑取消发送
				if (this.initPoint.Y - touche.clientY >= uni.upx2px(100)) {
					this.willStop = true;
					this.recordTis = '松开手指 取消发送';
				} else {
					this.willStop = false;
					this.recordTis = '手指上滑 取消发送';
				}
			},
			onRecordStart (e) {
				try{
					if (e.touches.length > 1) {
						return;
					}
					this.recordTis = '语音输入中';
					this.initPoint.Y = e.touches[0].clientY;
					this.initPoint.identifier = e.touches[0].identifier;
					this.recordLength = 0;
					this.recordTimer = setInterval(() => {
						this.recordLength++;
					}, 1000);
					recorderManager.start();
				}catch(e){
					uni.showModal({
						title: '录音错误',
						content : '请在app和小程序端体验录音，Uni官方明确H5不支持getRecorderManager, 详情查看Uni官方文档'
					});
				}
			},
			voiceCancel() {
				this.recording = false;
				this.voiceTis = '按住 说话';
				this.recordTis = '手指上滑 取消发送';
				this.willStop = true; //不发送录音
				clearInterval(this.recordTimer);
				recorderManager.stop(); //录音结束
			},
			onRecordEnd () {
				try{
					recorderManager.stop();
				}catch(e){
					console.log(e)
				}
			},
			async recordEnd(e) {
				clearInterval(this.recordTimer);
				if (!this.willStop) {
					// 发送
					clearInterval(this.recordTimer);
					if (this.recordLength < 1) {
						// 校验录音长短
						uniShowToast('录音时间过短, 最起码1秒', false);
						return;
					}
			
					console.log('e: ' + JSON.stringify(e));
					let voiceMessage = await createVoiceMessage.call(this, e);
			
					/**
					 * 创建音频信息
					 * @return {{length: number , url}}
					 */
					async function createVoiceMessage(e) {
						// 获取token
						let {
							token
						} = await beforeForSendFile(RongIMLib.FILE_TYPE.AUDIO);
						// 构造一个fileRes
						let fileRes = {
							tempFilePaths: [e.tempFilePath],
						};
						// 获取下载url
						let url = await uploadQiNiu(
							fileRes,
							token,
							RongIMLib.FILE_TYPE.AUDIO
						);
						return {
							duration: this.recordLength,
							remoteUrl: url,
							type: 'aac',
						};
					}
			
					this.sendVoiceMessageRong(voiceMessage, MSG_TYPE().AUDIO);
				} else {
					console.log('取消发送录音');
				}
				this.willStop = false;
			},
			async toSendImage() {
				// this.chattingHouseItem = {};
				// this.hideEmoji();
				let _this = this;
			
				let {
					token
				} = await beforeForSendFile();
				uniChooseImage({
					success: async function(chooseRes) {
						// console.log('chooseRes:', chooseRes)
						if (chooseRes.tempFiles[0].size > 8 * 1024 * 1000) {
							//上传图片大小限制
							uniShowToast('上传图片不可大于8MB');
						}
						let [
							// resultBase64,
							imageUri,
						] = await Promise.all([
							// pathToBase64(chooseRes.tempFiles[0].path),
							uploadQiNiu(chooseRes, token),
						]);
						// console.log('resultBase64: ',resultBase64, )
						let resultBase64 = 'data:image/png;';
						let resMsg = await cloudSendMessage({
								imageUri: imageUri.toString(),
								content: resultBase64,
							},
							MSG_TYPE().IMAGE
						);
						// console.log('resMsg', resMsg)
						_this.updateChatList(resMsg);
					},
				});
			},
			showImageFullScreen (e) {
				var imagesUrl = [e.currentTarget.dataset.url];
				uni.previewImage({
					urls: imagesUrl
				});
			},
			playVideo (e) {
				this.video.visible = true;
				this.video.url = e.currentTarget.dataset.url;
				this.$nextTick(() => {
					this.video.context.requestFullScreen({
						direction : 0
					});
					this.video.context.play();
				});
			},
			onVideoFullScreenChange (e) {
				//当退出全屏播放时，隐藏播放器
				if(this.video.visible && !e.detail.fullScreen){
				    this.video.visible = false;
				    this.video.context.stop();
				}
			},
			messageInputFocusin () {
				this.more.show = false;
				this.emoji.show = false
			},
			showEmoji () {
				this.emoji.show = !this.emoji.show;
				this.more.show = false;
			},
			showMore () {
				this.more.show = !this.more.show;
				this.emoji.show = false
			},
			selectEmoji (emojiKey) {
				this.content +=emojiKey
			},
			scrollToBottom () {
				this.$nextTick(function(){
					uni.pageScrollTo({
						scrollTop: 2000000,
						duration : 10
					})
				});
			},
		}
	}
</script>

<style lang="scss" scoped>
	// @import '../../../assets/styles/global';
	@import '../css/style';
	.chatting-main {
		// 注意 这个是scroll into view 奏效的必要属性
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		margin: auto;
		display: flex;
		flex-direction: row;
	
		.msg-list-main {
			padding-bottom: constant(safe-area-inset-bottom);
			padding-bottom: env(safe-area-inset-bottom);
			box-sizing: content-box;
			top: 0;
			/*margin-top: 3vw;*/
			margin-bottom: 13vw;
			flex: 1;
			position: relative;
	
			/*background-color: yellow;*/
			.more {
				margin-top: 3vw;
				width: 100vw;
				// @include center;
				color: rgba(128, 128, 128, 0.48);
				font-size: 15px;
				margin-bottom: 5vw;
			}
		}
	
		.time-message-block {
			padding: 20rpx 17px 20rpx 17px;
			width: 100%;
			position: relative;
	
			.time {
				margin-top: 5px;
				width: 100%;
				// @include center;
				height: 20px;
				font-size: 14px;
				color: #c8c9cc;
				margin-bottom: 15px;
			}
	
			.opposite,
			.mine {
				display: flex;
				justify-content: flex-start;
				align-items: flex-start;
	
				.profile-photo {
					// @include cover-no-repeat-center;
					width: 40px;
					height: 40px;
					background-color: #d8d8d8;
					border-radius: 50%;
					margin-right: 13px;
				}
	
				.message-block {
					padding: 5rpx 20rpx 2rpx;
					max-width: 78vw;
					min-height: 65rpx;
					background-color: #ebedf0;
					line-height: 6vw;
					border-top-left-radius: 0;
					border-top-right-radius: 3vw;
					font-size: 4vw;
					//@include center;
					display: flex;
					flex-direction: column;
					// @include borderBottomRadius;
	
					.bubble {
						width: 100%;
						height: 100%;
						// @include center;
						justify-content: space-between;
	
						.icon {
							font-size: 4vw;
						}
	
						.my-voice {
							// 调用别人的图标库, 命名记住my-voice就行
							color: #494949;
							transform: rotate(180deg);
						}
					}
	
					.msg-time {
						font-size: 19rpx;
						color: #636363;
						width: 100%;
						text-align: right;
					}
				}
	
				.image-message {
					background-color: black;
					width: 24vw;
					height: 29vw;
					border-radius: 1vw;
					// @include contain-no-repeat-center;
	
					.image {}
				}
			}
	
			.mine {
				flex-direction: row-reverse;
	
				.profile-photo {
					margin-right: 0;
					margin-left: 13px;
				}
	
				.message-block {
					background-color: #183a6a;
					color: white;
					// @include borderBottomRadius;
					border-top-left-radius: 3vw;
					border-top-right-radius: 0 !important;
	
					.msg-time {
						color: #93bdff;
						text-align: left;
					}
	
					.bubble {
						.my-voice {
							color: white;
							transform: rotate(0deg);
						}
					}
				}
			}
		}
	}
</style>
